package cn.shujuhai.qtadmin.platform.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.shujuhai.qtadmin.platform.domain.Permission;
import cn.shujuhai.qtadmin.platform.domain.PermissionMenu;
import cn.shujuhai.qtadmin.platform.domain.RolePermission;
import cn.shujuhai.qtadmin.platform.pluging.logging.BusinessType;
import cn.shujuhai.qtadmin.platform.pluging.logging.Logging;
import cn.shujuhai.qtadmin.platform.pluging.result.Result;
import cn.shujuhai.qtadmin.platform.service.PermissionMenuService;
import cn.shujuhai.qtadmin.platform.service.PermissionService;

/**
 * 用户API
 *
 * @author dch798
 * @date 2021/08/21 22:13
 **/
@RestController
@RequestMapping("admin/permission")
public class AdminPermissionController {

    public static final String CODE = "code";
    public static final String PERMISSION_ID = "permission_id";

    final PermissionService permissionService;
    final PermissionMenuService permissionMenuService;

    public AdminPermissionController(PermissionMenuService permissionMenuService, PermissionService permissionService) {
        this.permissionMenuService = permissionMenuService;
        this.permissionService = permissionService;
    }

    /**
     *
     * @param page
     *            当前页
     * @return 角色列表
     */
    @PostMapping("permissionList")
    @Logging(title = "权限列表", describe = "权限列表", type = BusinessType.QUERY)
    public Result permissionList(Integer page, Integer limit, @NotNull Permission permission) {
        PageMethod.startPage(page == 0 ? 1 : page, limit == 0 ? 15 : limit);
        var queryWrapper = new QueryWrapper<Permission>();
        if (CharSequenceUtil.isNotBlank(permission.getCode())) {
            queryWrapper.like("code", permission.getCode());
        }
        if (CharSequenceUtil.isNotBlank(permission.getName())) {
            queryWrapper.like("name", permission.getName());
        }
        var permissionList = permission.selectList(queryWrapper);
        return Result.success("获取成功", new PageInfo<>(permissionList));
    }

    /**
     *
     * @param roleId
     *            角色Id
     * @return 权限列表
     */
    @PostMapping("permissions")
    @Logging(title = "权限树", describe = "权限树", type = BusinessType.QUERY)
    public Result permissions(Integer roleId) {
        var permissions = new Permission().selectAll();
        var checkedIds = new RolePermission().selectList(new QueryWrapper<RolePermission>().eq("role_id", roleId));
        var checkedId = checkedIds.stream().map(RolePermission::getPermissionId).distinct().toArray(Long[]::new);
        var map = new HashMap<String, Object>(2);
        map.put("permissions", permissions);
        map.put("checkedId", checkedId);
        return Result.success("获取成功", map);
    }

    /**
     *
     * @param permission
     *            权限信息
     * @return 新增权限结果
     */
    @PostMapping("permissionAdd")
    @Transactional(rollbackFor = Exception.class)
    @Logging(title = "新增权限", describe = "新增权限", type = BusinessType.ADD)
    public Result permissionAdd(@NotNull Permission permission) {
        if (permission
            .selectCount(new QueryWrapper<Permission>().eq(CODE, CharSequenceUtil.trim(permission.getCode()))) > 0) {
            return Result.failure("该权限已经存在");
        }
        if (permission.insert() && ObjectUtil.isNotEmpty(permission.getMenus())) {
            var permissionMenus = new ArrayList<PermissionMenu>();
            for (Long menuId : permission.getMenus()) {
                var permissionMenu = new PermissionMenu();
                permissionMenu.setPermissionId(permission.getId());
                permissionMenu.setMenuId(menuId);
                permissionMenus.add(permissionMenu);
            }
            this.permissionMenuService.saveBatch(permissionMenus);
        }
        return Result.success("新增成功");
    }

    /**
     *
     * @param permission
     *            权限信息
     * @return 修改权限结果
     */
    @PostMapping("permissionUpdate")
    @Transactional(rollbackFor = Exception.class)
    @Logging(title = "修改权限", describe = "修改权限", type = BusinessType.EDIT)
    public Result permissionUpdate(@NotNull Permission permission) {
        if (permission.updateById() && ObjectUtil.isNotEmpty(permission.getMenus())) {
            var permissionMenus = new ArrayList<PermissionMenu>();
            for (Long menuId : permission.getMenus()) {
                var permissionMenu = new PermissionMenu();
                permissionMenu.setPermissionId(permission.getId());
                permissionMenu.setMenuId(menuId);
                permissionMenus.add(permissionMenu);
            }
            this.permissionMenuService.remove(new QueryWrapper<PermissionMenu>().eq(PERMISSION_ID, permission.getId()));
            this.permissionMenuService.saveBatch(permissionMenus);

        }
        return Result.success("修改成功");
    }

    /**
     *
     * @param id
     *            id
     * @return result
     */
    @PostMapping("permissionDelete")
    @Transactional(rollbackFor = Exception.class)
    @Logging(title = "权限删除", describe = "权限删除", type = BusinessType.REMOVE)
    public Result permissionDelete(Long id) {
        var ids = new ArrayList<Long>();
        ids.add(id);
        var allPermissions = this.permissionService.list();
        this.getChildrenPermissions(id, allPermissions, ids);
        if (new RolePermission().selectCount(new QueryWrapper<RolePermission>().in(PERMISSION_ID, ids)) <= 0) {
            this.permissionService.removeByIds(ids);
            this.permissionMenuService.remove(new QueryWrapper<PermissionMenu>().in(PERMISSION_ID, ids));
            return Result.success("删除成功");
        }
        return Result.failure("该角色已经分配给用户，删除失败");
    }

    /**
     *
     * @param id
     *            id
     * @param allPermissions
     *            allRoles
     * @param ids
     *            ids
     */
    private void getChildrenPermissions(Long id, @NotNull List<Permission> allPermissions, List<Long> ids) {
        var childrens = allPermissions.stream().filter(s -> s.getParentId().equals(id)).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(childrens)) {
            childrens.forEach(x -> {
                ids.add(x.getId());
                this.getChildrenPermissions(x.getId(), allPermissions, ids);
            });
        }
    }
}
